package org.example.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Collections;
import java.util.List;

@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {
    public MyGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {

        return (exchange, chain) -> {
            // 获取数据列表
            List<String> dataList = config.getValues();
            // 获取原始请求对象
            ServerHttpRequest request = exchange.getRequest();
            // 获取原始URI
            URI uri = request.getURI();//
            // 构建新的URI，将数据列表作为查询参数添加到原始URI中
            URI newUri = UriComponentsBuilder.fromUri(uri)
                    .queryParam("data", dataList.toArray())// 将数据列表作为查询参数添加到URI中
                    .build()// 构建新的URI
                    .toUri();// 获取新的URI
            // 构建新的请求对象
            ServerHttpRequest newRequest = request.mutate()
                    .uri(newUri)
                    .build(); // 传递修改后的请求对象，并继续处理
            // 传递修改后的请求并继续处理
            return chain.filter(exchange.mutate().request(newRequest).build()).then(
                    Mono.fromRunnable(
                            () -> exchange.getResponse().getHeaders().add("Custom-Header", "header-value")
                    )
            );// 传递修改后的请求对象，并继续处理
        };
    }

    @Override
    public ShortcutType shortcutType() {
        return ShortcutType.DEFAULT;
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return List.of("values");
    }
    public static class Config {
        private  List<String> values;
        public Config() {
        }
        public Config(List<String> values) {
            this.values = values;
        }
        public List<String> getValues() {
            return values;
        }
        public void setValues(List<String> values) {
            this.values = values;
        }
    }
}
